package com.tsf.hbase.jpa.dao;

import com.tsf.hbase.RowKey;
import com.tsf.hbase.jpa.Page;

import java.util.Collection;
import java.util.List;

/**
 * <p>hbase DAO层操作选项基本定义，子类可以自己实现此接口类，自定义接口方法实现或扩展</p>
 *
 * @author taoningbo
 * @since 1.0, Created as 2018/11/26
 * @param <T> 实体对象类型
 */
public interface HBaseDao<T, RK extends RowKey> {

    /**
     * 新增一个实体数据.
     *
     * @param entity 待存储的实体对象
     * @return 返回存储结果，如果存储成功则返回‘true’，否则返回‘false’
     */
    boolean save(T entity);

    /**
     * 新增一批实体数据.
     *
     * @param entities 待存储的实体对象集合
     * @return 返回存储结果，如果存储成功则返回‘true’，否则返回‘false’
     */
    boolean save(Collection<T> entities);

    /**
     * 根据ID查询一条记录.
     *
     * @param rowKey hbase数据表行主键，也是唯一索引
     * @return 返回一个实体查询结果
     */
    T get(RK rowKey);

    /**
     * 根据ID查询一条记录.
     *
     * @param rowKey hbase数据表行主键，也是唯一索引
     * @return 返回一个实体查询结果
     */
    T get(byte[] rowKey);

    /**
     * 根据ID查询一条记录.
     *
     * @param rowKey hbase数据表行主键，也是唯一索引（byte[]类型的row进行Base64编码后的结果字符串）
     * @return 返回一个实体查询结果
     */
    T get(String rowKey);

    /**
     * 查询hbase中的所有符合{@code gets}的数据，当数据量较大是一般不建议使用，建议使用分页查询.
     *
     * @param rows rows
     * @return 返回所有符合条件的实体对象集合，不分页，数据量大时不建议使用
     */
    Collection<T> get(List<RK> rows);

    /**
     * 查询hbase中的所有数据，当数据量较大时一般不建议使用，建议使用分页查询.
     *
     * @return 返回hbase表中的所有数据
     */
    Collection<T> scan();

    /**
     * 根据指定的{@code rowKey}查询所有匹配到的数据，当数据量较大是一般不建议使用，建议使用分页查询.
     *
     * @param rowKey 实体对象
     * @return 返回所有符合条件的实体对象集合，不分页，数据量大时不建议使用
     */
    Collection<T> scan(RK rowKey);

    /**
     * 根据指定的{@code rowKey}查询所有匹配到的数据，默认分页查询.
     *
     * @param rowKey 实体对象
     * @param page   分页对象
     * @return 返回所有符合条件的实体对象集合，最多返回{@link Page#DEFAULT_MAX_PAGE_SIZE}的数据，
     * 最少返回{@link Page#DEFAULT_MIN_PAGE_SIZE}
     */
    Collection<T> pagingScan(RK rowKey, Page page);

    /**
     * 根据指定的{@code rowKey}查询所有匹配到的数据并满足开始时间{@code startTime}至当前系统时间
     * 之间的数据，默认分页查询.
     *
     * @param rowKey    实体对象
     * @param page      分页对象
     * @param startTime 开始时间
     * @return 返回所有符合条件的实体对象集合，最多返回{@link Page#DEFAULT_MAX_PAGE_SIZE}的数据，
     * 最少返回{@link Page#DEFAULT_MIN_PAGE_SIZE}
     */
    Collection<T> pagingScan(RK rowKey, Page page, Long startTime);

    /**
     * 根据指定的{@code rowKey}查询所有匹配到的数据并满足开始时间{@code startTime}至结束时间
     * {@code endTime}之间的数据，默认分页查询.
     *
     * @param rowKey    实体对象
     * @param page      分页对象
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 返回所有符合条件的实体对象集合，最多返回{@link Page#DEFAULT_MAX_PAGE_SIZE}的数据，
     * 最少返回{@link Page#DEFAULT_MIN_PAGE_SIZE}
     */
    Collection<T> pagingScan(RK rowKey, Page page, Long startTime, Long endTime);

    /**
     * 根据实体中指定的数据查询所有匹配的数据，默认分页查询.
     *
     * @param entity 实体对象
     * @param page   分页对象
     * @return 返回所有符合条件的实体对象集合，最多返回{@link Page#DEFAULT_MAX_PAGE_SIZE}的数据，
     * 最少返回{@link Page#DEFAULT_MIN_PAGE_SIZE}
     */
    Collection<T> pagingFilterScan(T entity, Page page);

    /**
     * 根据实体{@code entity}中指定的数据查询所有匹配的数据并满足开始时间{@code startTime}至当前系统时间
     * 之间的数据，默认分页查询.
     *
     * @param entity    实体对象
     * @param page      分页对象
     * @param startTime 开始时间
     * @return 返回所有符合条件的实体对象集合，最后返回{@link Page#DEFAULT_MAX_PAGE_SIZE}的数据，
     * 最少返回{@link Page#DEFAULT_MIN_PAGE_SIZE}
     */
    Collection<T> pagingFilterScan(T entity, Page page, Long startTime);

    /**
     * 根据实体{@code entity}中指定的数据查询所有匹配的数据并满足开始时间{@code startTime}至结束时间
     * {@code endTime}之间的数据，默认分页查询.
     *
     * @param entity    实体对象
     * @param page      分页对象
     * @param startTime 开始时间
     * @param endTime   结束时间
     * @return 返回所有符合条件的实体对象集合，最后返回{@link Page#DEFAULT_MAX_PAGE_SIZE}的数据，
     * 最少返回{@link Page#DEFAULT_MIN_PAGE_SIZE}
     */
    Collection<T> pagingFilterScan(T entity, Page page, Long startTime, Long endTime);

    /*
     * 弃用的接口方法，此处列出只为兼容老接口
     */

    @Deprecated
    default T findOne(RK rowKey) {
        return get(rowKey);
    }

    @Deprecated
    default T findOne(byte[] rowKey) {
        return get(rowKey);
    }

    @Deprecated
    default T findOne(String rowKey) {
        return get(rowKey);
    }

    @Deprecated
    default Collection<T> findAll() {
        return scan();
    }

    @Deprecated
    default Collection<T> findAllBy(RK rowKey) {
        return scan(rowKey);
    }

    @Deprecated
    default Collection<T> findAllBy(RK rowKey, Page page) {
        return pagingScan(rowKey, page);
    }

    @Deprecated
    default Collection<T> findAllBy(RK rowKey, Page page, Long startTime) {
        return pagingScan(rowKey, page, startTime);
    }

    @Deprecated
    default Collection<T> findAllBy(RK rowKey, Page page, Long startTime, Long endTime) {
        return pagingScan(rowKey, page, startTime, endTime);
    }

    @Deprecated
    default Collection<T> findAllBy(T entity, Page page) {
        return pagingFilterScan(entity, page);
    }

    @Deprecated
    default Collection<T> findAllBy(T entity, Page page, Long startTime) {
        return pagingFilterScan(entity, page, startTime);
    }

    @Deprecated
    default Collection<T> findAllBy(T entity, Page page, Long startTime, Long endTime) {
        return pagingFilterScan(entity, page, startTime, endTime);
    }
}
